/**
 * 工具提示组件
 * 负责创建、显示和更新工具提示内容
 */

import { resolveTarget } from './helpers';
import { EventEmitter } from '../common/event-emitter';

/**
 * TooltipUI配置选项
 */
export interface TooltipUiOptions {
  /** 内容配置项 */
  content: ContentUpdateData;
  /** 目标元素或选择器 */
  target: string | HTMLElement;
  /** 显示方向 */
  direction?: 'top' | 'bottom' | 'left' | 'right' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'left-top' | 'right-top' | 'left-bottom' | 'right-bottom';
}

export interface ContentUpdateData {
    type: 'html' | 'text' | 'element';
    content: string | HTMLElement;
}

export class TooltipUI extends EventEmitter {
    /** 提示框DOM元素 */
    private __element: HTMLDivElement;

    /** 工具提示配置选项 */
    private __options: TooltipUiOptions;

    /**
     * 创建工具提示实例
     * @param {TooltipUiOptions} options - 工具提示配置选项
     */
    constructor(options: TooltipUiOptions) {
        super();
        this.__options = { direction: 'bottom', ...options };
        const targetElement = resolveTarget(options.target);
        this.__element = this.createElement();
        this.__bindEventListeners();
        this.update(this.__options.content);
        targetElement.style.position = targetElement.style.position || 'relative';
        targetElement.appendChild(this.__element);
    }

    /**
     * 创建工具提示DOM元素
     * @returns {HTMLDivElement} 配置好的工具提示元素
     * @private
     */
    private createElement(): HTMLDivElement {
        const tooltip = document.createElement('div');
        const { direction } = this.__options;
        const positions = {
            top: 'bottom: 100%; left: 50%; transform: translateX(-50%);',
            bottom: 'top: 100%; left: 50%; transform: translateX(-50%);',
            left: 'right: 100%; top: 50%; transform: translateY(-50%);',
            right: 'left: 100%; top: 50%; transform: translateY(-50%);',
            'top-left': 'bottom: 100%; left: 0;',
            'left-top': 'bottom: 100%; left: 0;',
            'top-right': 'bottom: 100%; right: 0;',
            'right-top': 'bottom: 100%; right: 0;',
            'bottom-left': 'top: 100%; left: 0;',
            'left-bottom': 'top: 100%; left: 0;',
            'bottom-right': 'top: 100%; right: 0;',
            'right-bottom': 'top: 100%; right: 0;'
        };

        tooltip.style.cssText = `
            position: absolute;
            ${positions[direction || 'bottom']}
            background: rgba(0,0,0,0.8);
            color: white;
            padding: 8px 12px;
            border-radius: 4px;
            font-size: 12px;
            white-space: nowrap;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.2s;
            z-index: 5210;
            text-align: left;
        `;
        return tooltip;
    }

    /**
     * 更新工具提示内容（通过事件）
     */
    public update(data: ContentUpdateData): void {
        this.emit<ContentUpdateData>('contentUpdate', data);
    }

    /**
     * 显示工具提示（通过事件）
     */
    public show(): void {
        this.emit('visibilityChange', true);
    }

    /**
     * 隐藏工具提示（通过事件）
     */
    public hide(): void {
        this.emit('visibilityChange', false);
    }

    /**
     * 初始化事件监听
     */
    private __bindEventListeners(): void {
        this.on<ContentUpdateData>('contentUpdate', (content: ContentUpdateData) => {
           if (typeof content !== 'object' || content === null) {
                throw new Error('内容更新失败：content必须是对象');
            } else if (content.type === 'html' && typeof content.content === 'string') {
                this.__element.innerHTML = content.content;
            } else if (content.type === 'text' && typeof content.content === 'string') {
                this.__element.textContent = content.content;
            } else if (content.type === 'element' && content.content instanceof HTMLElement) {
                this.__element.innerHTML = '';
                this.__element.appendChild(content.content);
            } else {
                throw new Error('内容更新失败：type必须是html、text或element，content必须是字符串或HTMLElement');
            }
        });

        this.on<boolean>('visibilityChange', (visible: boolean) => {
           if (typeof visible !== 'boolean') {
                throw new Error('可见性变更失败：必须提供布尔值');
            }
            this.__element.style.opacity = visible ? '1' : '0';
        });
    }

    /**
     * 获取工具提示DOM元素
     * @returns {HTMLDivElement} 工具提示元素
     */
    public getElement(): HTMLDivElement {
        return this.__element;
    }
}